#include "ErrorCode.h"
#include "TCPClient.h"
#include "TCPServer.h"
#include "UDPClient.h"
#include "UDPServer.h"
#include <iostream>


// Define Windows and linux Thread function
#ifndef _WINDOWS
#include <pthread.h>
#include <unistd.h>
void* ServerThread(void*);
void* ClientThread(void*);
#define SLEEP(X) sleep(X)
#else
#include <windows.h>
DWORD WINAPI ServerThread(LPVOID);
DWORD WINAPI ClientThread(LPVOID);
#define SLEEP(X) Sleep(X * 1000)
#endif //!_WINDOWS


int main(int argc, char **argv)
{
// Choose Windows or linux create thread function
#ifndef _WINDOWS
	pthread_t pidServer, pidClient;
	pthread_create(&pidServer, NULL, ServerThread, NULL);
	SLEEP(5);
	pthread_create(&pidClient, NULL, ClientThread, NULL);
	pthread_join(pidServer, NULL);
	pthread_join(pidClient, NULL);
#else
	WSADATA wsaData;
	WORD wVersionRequested = MAKEWORD(2, 2);
	WSAStartup(wVersionRequested, &wsaData);

	HANDLE handleServer = CreateThread(NULL, 0, ServerThread, NULL, 0, NULL);
	SLEEP(5);
	HANDLE handleClient = CreateThread(NULL, 0, ClientThread, NULL, 0, NULL);
	WaitForSingleObject(handleServer, INFINITE);
	WaitForSingleObject(handleClient, INFINITE);

	WSACleanup();
	system("pause");
#endif //!_WINDOWS
	return 0;
}



#ifndef _WINDOWS
void* ServerThread(void*)
#else
DWORD WINAPI ServerThread(LPVOID)
#endif //!_WINDOWS
{
	int nRet = NETDEBUG_SUCCESS;
	std::string strSend;
	std::string strRecv;
	
	// TCP Server Sample
	strSend = "Hello, Client!";
	strRecv = "";
	CTCPServer *tcpserver = new CTCPServer();
	nRet = tcpserver->StartServer("127.0.0.1", 11122, 10);
	if (NETDEBUG_SUCCESS != nRet)
	{
		std::cout << "Start TCP server fail" << std::endl;
		return NULL;
	}
	CSocket *client = tcpserver->Accept();
	if (NULL == client)
	{
		std::cout << "TCP accept client fail" << std::endl;
		return NULL;
	}
	
	client->Send(strSend);
	client->Recv(strRecv);
	std::cout << "TCP server Send : " << strSend << std::endl;
	std::cout << "TCP server Recv : " << strRecv << std::endl;
	delete client;
	delete tcpserver;

	// UDP Server Sample
	strSend = "Hello, Client!";
	strRecv = "";
	CUDPServer *udpserver = new CUDPServer();
	nRet = udpserver->StartServer("127.0.0.1", 11123);
	if (NETDEBUG_SUCCESS != nRet)
	{
		std::cout << "Start UDP server fail" << std::endl;
		return NULL;
	}
	udpserver->Recv(strRecv);
	udpserver->Send(strSend);
	std::cout << "UDP server Send : " << strSend << std::endl;
	std::cout << "UDP server Recv : " << strRecv << std::endl;
	delete udpserver;

	return NULL;
}

#ifndef _WINDOWS
void* ClientThread(void*)
#else
DWORD WINAPI ClientThread(LPVOID)
#endif //!_WINDOWS
{
	int nRet = NETDEBUG_SUCCESS;
	std::string strSend;
	std::string strRecv;
	
	// TCP Client Sample
	strSend = "Hello, Server!";
	strRecv = "";
	CTCPClient *tcpclient = new CTCPClient();
	nRet = tcpclient->Connect("127.0.0.1", 11122);
	if (NETDEBUG_SUCCESS != nRet)
	{
		std::cout << "Connect TCP server fail" << std::endl;
		return NULL;
	}
	tcpclient->Recv(strRecv);
	tcpclient->Send(strSend);
	std::cout << "TCP client Recv : " << strRecv << std::endl;
	std::cout << "TCP client Send : " << strSend << std::endl;
	delete tcpclient;

	// UDP Client Sample
	strSend = "Hello, Server!";
	strRecv = "";
	CUDPClient *udpclient = new CUDPClient();
	nRet = udpclient->Connect("127.0.0.1", 11123);
	if (NETDEBUG_SUCCESS != nRet)
	{
		std::cout << "Connect UDP server fail" << std::endl;
		return NULL;
	}
	udpclient->Send(strSend);
	SLEEP(5);
	udpclient->Recv(strRecv);
	std::cout << "UDP client Recv : " << strRecv << std::endl;
	std::cout << "UDP client Send : " << strSend << std::endl;
	delete udpclient;

	return NULL;
}